package com.fenquen.dfs.base.protocol.data.storage_source.req_from_storage;

import com.alibaba.fastjson.annotation.JSONField;
import com.fenquen.dfs.base.protocol.Protocol;
import com.fenquen.dfs.base.protocol.data.storage_source.StorageSource;
import com.fenquen.dfs.base.utils.BiUtils;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

/**
 * 存储节点向路由节点上报的文件删除or上传结果的回执
 */
public class Report extends ReqFromStorage {

    /**
     * 32字节,上传文件的唯一标识符
     */
    public String uploadFileUUID;
    public static final int uploadFileUUIDByteLength = 32;

    /**
     * 1个字节,0代表删除1代表添加
     */
    public Byte flag;
    public static final int flagByteLength = 1;

    public interface Flag {
        byte 删除 = 0x00;
        byte 添加 = 0x01;
    }

    /**
     * 1个字节,上传有没有成功<br>
     * 0失败1成功
     */
    public Byte success;
    public static final int successByteLength = 1;

    public interface Success {
        byte 失败 = 0x00;
        byte 成功 = 0x01;
    }

    /**
     * 1个字节,消息的长度
     */
    public Integer msgLength;
    public static final int msgLengthByteLength = 1;

    /**
     * 要是上传失败一般不会为empty
     */
    public String msg;

    /**
     * 1个字节,原始文件名字的长度
     */
    public Integer originFileNameLength;
    public static final int originFileNameLengthByteLength = 1;

    /**
     * 原始的文件名字
     */
    public String originFileName;

    /**
     * 1个字节,格式名字的长度
     */
    public Integer extNameLength;
    public static final int extNameLengthByteLength = 1;

    /**
     * 格式名字
     */
    public String extName;

    /**
     * 4个字节,对应的存储节点的ip
     */
    public String host;
    public static final int hostByteLength = 4;

    /**
     * 2个字节,对应的存储节点的port
     */
    public Integer port;
    public static final int portByteLength = 2;

    /**
     * 8个字节,时间
     */
    // public Long timestamp;
    @Override
    public StorageSource parseBinary(ByteBuffer byteBuffer) {
        byte[] temp;

        temp = new byte[uploadFileUUIDByteLength];
        byteBuffer.get(temp);
        uploadFileUUID = new String(temp);

        flag = byteBuffer.get();
        success = byteBuffer.get();

        msgLength = BiUtils.getUByte(byteBuffer.get());
        if (msgLength > 0) {
            temp = new byte[msgLength];
            byteBuffer.get(temp);
            msg = new String(temp);
        }

        originFileNameLength = BiUtils.getUByte(byteBuffer.get());
        temp = new byte[originFileNameLength];
        byteBuffer.get(temp);
        originFileName = new String(temp);

        extNameLength = BiUtils.getUByte(byteBuffer.get());
        temp = new byte[extNameLength];
        byteBuffer.get(temp);
        extName = new String(temp);

        temp = new byte[4];
        byteBuffer.get(temp);
        host = BiUtils.bytes2Ip(temp);

        port = BiUtils.getUShort(byteBuffer.getShort());

        return this;
    }

    @JSONField(serialize = false)
    @Override
    public int getByteLength() {
        return uploadFileUUIDByteLength +
                flagByteLength +
                successByteLength +
                msgLengthByteLength +
                msgLength +
                originFileNameLengthByteLength +
                originFileNameLength +
                extNameLengthByteLength +
                extNameLength +
                hostByteLength +
                portByteLength;
    }

    @JSONField(serialize = false)
    @Override
    public byte[] getByteArr() {
        ByteBuffer byteBuffer = ByteBuffer.allocate(getByteLength());

        byteBuffer.put(uploadFileUUID.getBytes(StandardCharsets.UTF_8));
        byteBuffer.put(flag);
        byteBuffer.put(success);

        byteBuffer.put((byte) (msgLength & 0xff));
        if (msgLength > 0) {
            byteBuffer.put(msg.getBytes(StandardCharsets.UTF_8));
        }

        byteBuffer.put((byte) (originFileNameLength & 0xff));
        byteBuffer.put(originFileName.getBytes(StandardCharsets.UTF_8));

        byteBuffer.put((byte) (extNameLength & 0xff));
        byteBuffer.put(extName.getBytes(StandardCharsets.UTF_8));

        byteBuffer.put(BiUtils.ip2ByteArr(host));

        byteBuffer.putShort((short) (port & 0xffff));

        return byteBuffer.array();
    }

    @Override
    public Byte getProtocolType() {
        return Protocol.ProtocolType.ReqFromStorage.存储节点文件上传回执;
    }

    @JSONField(serialize = false)
    public String getAddr() {
        return host + ":" + port;
    }
}
